package service

import (
	"strconv"
	"zg3/config"
	"zg3/internal/api/request"
	"zg3/internal/models/dao"
	"zg3/pkg"
)

func CreateGroup(create *request.GroupCreate, userId int) string {
	tx := config.DB.Begin()
	group := dao.Group{
		GroupName:       create.GroupName,
		GroupHeardImage: create.GroupHeardImage,
		GroupRemark:     create.GroupRemark,
	}
	err := tx.Create(&group).Error
	if err != nil {
		tx.Rollback()
		return "群聊创建失败"
	}
	var user *dao.User
	tx.Where("id=?", userId).Limit(1).Find(&user)
	groupMember := dao.GroupMember{
		UserId:        userId,
		GroupId:       int(group.ID),
		Type:          1,
		GroupNickName: user.NickName,
	}
	gt := dao.GroupTop{
		GroupId: int(group.ID),
		UserId:  userId,
		Top:     0,
	}
	tx.Create(&gt)
	tx.Create(&groupMember)
	for _, i := range create.UserId {
		var users *dao.User
		tx.Where("id=?", i).Limit(1).Find(&users)
		groupMembers := dao.GroupMember{
			UserId:        i,
			GroupId:       int(group.ID),
			Type:          3,
			GroupNickName: users.NickName,
		}
		groupTop := dao.GroupTop{
			GroupId: int(group.ID),
			UserId:  i,
			Top:     0,
		}
		err = tx.Create(&groupTop).Error
		if err != nil {
			tx.Rollback()
			return "群聊创建失败"
		}
		err = tx.Create(&groupMembers).Error
		if err != nil {
			tx.Rollback()
			return "群聊创建失败"
		}
	}
	tx.Commit()
	return ""
}

func GroupCheck(create *request.GroupCreate, userId int) string {
	for _, i := range create.UserId {
		var friend *dao.Friend
		config.DB.Where("user_id=? and friend_id=?", userId, i).Limit(1).Find(&friend)
		if friend.ID == 0 {
			return "用户" + strconv.Itoa(i) + "不是您的好友"
		}
	}
	return ""
}

func CreateDev(dev *request.CreateDev, userId int) string {
	var own *dao.GroupMember
	config.DB.Where("user_id=?", userId).Limit(1).Find(&own)
	if own.Type != 1 {
		return "您不是群主，没有设置管理员的权限"
	}
	var sli []*dao.GroupMember
	var group []*dao.GroupMember
	config.DB.Where("type=2 and group_id=?", dev.GroupId).Find(&sli)
	config.DB.Model(&dao.GroupMember{}).Find(&group)
	if len(sli) >= len(group)/3 {
		return "群管理已满"
	}
	err := config.DB.Model(&dao.GroupMember{}).Where("user_id=? and group_id=?", dev.UserId, dev.GroupId).
		Update("type", 2).Error
	if err != nil {
		return "管理员设置失败"
	}
	return ""
}

func CreateGroupMember(member *request.CreateGroupMember, userId int) string {
	tx := config.DB.Begin()
	var own *dao.GroupMember
	config.DB.Where("user_id=?", userId).Limit(1).Find(&own)
	if own.Type == 3 {
		return "您不是群主或管理员，没有设置邀请的权限"
	}
	if len(member.UserId) > 5 {
		return "您一次性只能邀请5个人"
	}
	for _, i := range member.UserId {
		var friend *dao.Friend
		config.DB.Where("user_id=? and friend_id=?", userId, i).Limit(1).Find(&friend)
		if friend.ID == 0 {
			return "用户" + strconv.Itoa(i) + "不是您的好友"
		}
	}
	for _, i := range member.UserId {
		var users *dao.User
		tx.Where("id=?", i).Limit(1).Find(&users)
		groupMembers := dao.GroupMember{
			UserId:        i,
			GroupId:       member.GroupId,
			Type:          3,
			GroupNickName: users.NickName,
		}
		err := tx.Create(&groupMembers).Error
		if err != nil {
			tx.Rollback()
			return "用户拉取失败"
		}
	}
	return ""
}

func DeleteMember(member *request.DeleteMember, userId int) string {
	var own *dao.GroupMember
	config.DB.Where("user_id=?", userId).Limit(1).Find(&own)
	if own.Type == 3 {
		return "您不是群主或管理员，没有移除用户的权限"
	}
	for _, i := range member.UserId {
		err := config.DB.Where("user_id=? and group_id=?", i, member.GroupId).Delete(&dao.GroupMember{}).Error
		if err != nil {
			return "删除群成员失败"
		}
	}
	return ""
}

func Close(close2 *request.Close, userId int) string {
	var own *dao.GroupMember
	config.DB.Where("user_id=?", userId).Limit(1).Find(&own)
	if own.Type != 1 {
		return "您不是群主，没有解散群的权限"
	}
	err := config.DB.Where("group_id=?", close2.GroupId).Delete(&dao.GroupMember{}).Error
	if err != nil {
		return "解散群失败"
	}
	err = config.DB.Where("id=?", close2.GroupId).Delete(&dao.Group{}).Error
	if err != nil {
		return "解散群失败"
	}
	return ""
}

func GiveYou(you *request.GiveYou, userId int) string {
	var own *dao.GroupMember
	config.DB.Where("user_id=?", userId).Limit(1).Find(&own)
	if own.Type != 1 {
		return "您不是群主，没有转让群主的权限"
	}
	err := config.DB.Model(&dao.GroupMember{}).Where("user_id=? and group_id=?", you.UserId, you.GroupId).
		Update("type", 1).Error
	if err != nil {
		return "群转让失败"
	}
	err = config.DB.Model(&dao.GroupMember{}).Where("user_id=? and group_id=?", userId, you.GroupId).
		Update("type", 3).Error
	if err != nil {
		return "群转让失败"
	}
	return ""
}

func GroupList(list *request.GroupList, userId int) []*dao.Group {
	var sli []*dao.Group
	var top []*dao.Group
	var friend []*dao.Group
	var groupTop []*dao.GroupTop
	config.DB.Where("user_id=?", userId).Find(&groupTop)
	for _, ds := range groupTop {
		if ds.Top == 1 {
			config.DB.Where("id=?", ds.GroupId).Order("group_name ASC").Find(&top)
			for _, d := range top {
				sli = append(sli, d)
			}
		} else {
			config.DB.Where("id=?", ds.GroupId).Order("group_name ASC").
				Scopes(Paginate(list.Page, list.PageSize)).Find(&friend)
			for _, d := range friend {
				sli = append(sli, d)
			}
		}
	}
	return sli
}

func GroupTop(top *request.GroupTop, userId int) {
	config.DB.Debug().Model(&dao.GroupTop{}).Where("user_id=? and group_id=?", userId, top.GroupId).Update("top", 1)
}

func GroupNoTop(top *request.GroupTop, userId int) {
	config.DB.Model(&dao.GroupTop{}).Where("user_id=? and group_id=?", userId, top.GroupId).Update("top", 0)
}

func CreateRemark(remark *request.CreateRemark, userId int) string {
	var own *dao.GroupMember
	config.DB.Where("user_id=?", userId).Limit(1).Find(&own)
	if own.Type == 3 {
		return "您不是群主或管理员，没有发布公告的权限"
	}
	var sli []*dao.GroupMember
	config.DB.Where("group_id=?", remark.GroupId).Find(&sli)
	rabbitmq := pkg.NewRabbitMQSimple(strconv.Itoa(remark.GroupId))
	for i := 0; i < len(sli); i++ {
		rabbitmq.PublishSimple(remark.Remark)
	}
	mes := dao.GroupMessage{
		UserId:  userId,
		GroupId: remark.GroupId,
		Content: remark.Remark,
		Type:    0,
	}
	config.DB.Create(&mes)
	return ""
}

func FindGroupId(userId int) []*dao.GroupMember {
	var sli []*dao.GroupMember
	config.DB.Where("user_id=?", userId).Find(&sli)
	return sli
}
